Comparison to Xarray


For users coming from an Xarray background, much of UXarray’s design is familiar. This notebook showcases an example of transitioning a Structured Grid Xarray workflow to UXarray.

Imports

import matplotlib.pyplot as plt
import uxarray as ux
import xarray as xr
fig_size = 400
plot_kwargs = {"backend": "matplotlib", "aspect": 2, "fig_size": fig_size}

Data

It is common practice to resample unstructured grids to a structured representation for many analysis workflows to utilize familiar and reliable tools.

The datasets used in this example are meant to mimic this workflow, with a source Unstructured Grid and a Structured representation of that same grid.

Structured

base_path = "../../meshfiles/"
ds_path = base_path + "outCSne30.structured.nc"
xrds = xr.open_dataset(ds_path)
xrds
<xarray.Dataset> Size: 30kB
Dimensions:  (lat: 45, lon: 80)
Coordinates:
  * lat      (lat) int64 360B -90 -86 -82 -78 -74 -70 -66 ... 66 70 74 78 82 86
  * lon      (lon) float64 640B -180.0 -175.5 -171.0 ... 166.5 171.0 175.5
Data variables:
    psi      (lat, lon) float64 29kB ...

Unstructured

base_path = "../../meshfiles/"
grid_filename = base_path + "outCSne30.grid.ug"
data_filename = base_path + "outCSne30.data.nc"
uxds = ux.open_dataset(grid_filename, data_filename)
uxds
<xarray.UxDataset> Size: 43kB
Dimensions:  (n_face: 5400)
Dimensions without coordinates: n_face
Data variables:
    psi      (n_face) float64 43kB 1.351 1.331 1.31 1.289 ... 0.6909 0.67 0.6495

Example Workflows

Below are two simple visualization workflows that someone would run into

  • Creating a single plot

  • Creating a pair of plots (two different plots are used to mimic different data)

Xarray

xrds["psi"].plot(figsize=(12, 5), cmap="inferno")
<matplotlib.collections.QuadMesh at 0x7fb42551f8b0>
../../_images/b59189f0e60db4a3be15f84866b53e452d6c1bc08fb949c8219e7a7b906aa4cf.png
fig, axs = plt.subplots(nrows=2, figsize=(12, 10))

xrds["psi"].plot(cmap="inferno", ax=axs[0])
xrds["psi"].plot(cmap="cividis", ax=axs[1])
<matplotlib.collections.QuadMesh at 0x7fb42417fd30>
../../_images/0eaeb0fbc25505828c457df778435770e9d57a35b7cebf85e181b3846a32952d.png

UXarray

uxds["psi"].plot(width=1000, height=500, cmap="inferno")

While the default UXarray plot looks good, to better replicate Xarray we can use the matplotlib backend paired with a raster plot.

ADD ADMONATION TO OTHER SECTION

uxds["psi"].plot.rasterize(method="polygon", cmap="inferno", **plot_kwargs)
(
    uxds["psi"].plot.rasterize(method="polygon", cmap="inferno", **plot_kwargs)
    + uxds["psi"].plot.rasterize(method="polygon", cmap="cividis", **plot_kwargs)
).opts(fig_size=fig_size).cols(1)

Xarray with hvPlot

One of the primary drawbacks to UXarray’s use of HoloViews for visualization is that there is no direct way to integrate plots generated with Xarray and UXarray together. This can be alleviated by using the hvPlot library, specifically hvplot.xarray, on Xarray’s data structures.

ADD ADMONATION TO HVPLOT!

import holoviews as hv
import hvplot.xarray

hv.extension("bokeh")

By using xrds.hvplot() as opposed to xrds.plot(), we can create a simple figure showcasing our Structured Grid figure from Xarray and Unstructured Grid figure from UXarray in a single plot.

hv.extension("bokeh")
(
    xrds.hvplot(cmap="inferno", title="Xarray with hvPlot", width=1000, height=500)
    + uxds["psi"].plot(cmap="inferno", title="UXarray Plot", width=1000, height=500)
).cols(1)

If we are not interested in the outlines of each polygon in our Unstructured Grid, we can create a raster plot, which will better match the result produced by Xarray.

ADD NOTE ABOUT POLYGON SECTION

hv.extension("matplotlib")
(
    xrds.hvplot(cmap="inferno", title="Xarray with hvPlot", aspect=2)
    + uxds["psi"].plot.rasterize(
        method="polygon", cmap="inferno", title="UXarray Plot", **plot_kwargs
    )
).opts(fig_size=fig_size).cols(1)

In addition to using hvPlot, the user could also use HoloViews or Datashader on Xarray’s data structures, but this cookbook will not go into detail.

ADD LINK TO EXAMPLES?